<?php
abstract class system_view_abstract implements system_view_interface {
	
	private $_strictVars = false;
	
	public function __construct() {
		$this->init();
	}
	public function init() {
	}
	
	public function __get($key) {
		if($this->_strictVars) {
			trigger_error('Key "' . $key . '" does not exist', E_USER_NOTICE);
		}		
		return null;
	}
	
	public function __isset($key) {
		if('_' != substr($key, 0, 1)) {
			return isset($this->$key);
		}		
		return false;
	}
	
	public function __set($key, $val) {
		if('_' != substr($key, 0, 1)) {
			$this->$key = $val;
			return;
		}
		throw new system_view_exception('Setting private or protected class members is not allowed');
	}
	
	public function __unset($key) {
		if('_' != substr($key, 0, 1) && isset($this->$key)) {
			unset($this->$key);
		}
	}
	
	protected $_helpers = array();
	public function getHelper($name) {
		$class = 'helper_' . $name;
		if(!isset($this->_helpers[$class])) {
			$baseDir = dirname($this->getBasePath()) . DIRECTORY_SEPARATOR . 'helper';
			$file = $baseDir . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $name) . '.php';
			if(file_exists($file)) {
				
				require_once $file;
				$this->_helpers[$class] = new $class();
				$this->_helpers[$class]->setView($this);
			} else {
				throw new system_view_exception('The helper ' . $name . ' is not exists');
			}
		}
		return $this->_helpers[$class];
	}
	
	public function __call($name, $args) {
		$helper = $this->getHelper($name);
		return call_user_func_array(array($helper, $name), $args);
	}

	protected static $backTemplate = array();
	protected static $template = null;
	static public function setTemplate($template) {
		if(is_array($template)) {
			if(!isset($template[0])) {
				sort($template);
			}
			$_template = $template[0];
			array_shift($template);
			self::$backTemplate = $template;
		} else {
			$_template = $template;
		}
		self::$template = $_template;
	}
	static public function getTemplate() {
		return self::$template;
	}
	
	private $_basePath = null;
	public function setBasePath($path) {
		$this->_basePath = $path;
		return $this;
	}
	public function getBasePath() {
		return $this->_basePath;
	}
	
	public function assign($spec, $value = null) {
		if(is_array($spec)) {
			foreach($spec as $k => $v) {
				$this->assign($k, $v);
			}
		} else {
			$this->{$spec} = $value;
		}
	}
	
	public function clearVars() {
		$vars = get_object_vars($this);
		foreach($vars as $k => $v) {
			if('_' != substr($k, 0, 1)) {
				unset($this->{$k});
			}
		}
		return $this;
	}
	
	public function escape($val) {
		return htmlspecialchars($val);
	}
	
	public function render($script, $once = false) {
		ob_start();
		$dir = $this->getBasePath() . DIRECTORY_SEPARATOR;
		$file = $dir . $script;
		if(self::getTemplate() !== null) {
			$file = $dir . self::getTemplate() . DIRECTORY_SEPARATOR . $script;
			if(!file_exists($file) && !empty(self::$backTemplate)) {
				foreach(self::$backTemplate AS $template) {
					$file = $dir . $template . DIRECTORY_SEPARATOR . $script;
					if(file_exists($file)) {
						break;
					}
				}
			}
		}
		if($once) {
			include_once $file;
		} else {
			include $file;
		}
		return ob_get_clean();
	}

}